"""
仪表盘服务层
"""
from models import Reservation, Room, Guest, RoomStatus
from extension import db
from datetime import datetime, timedelta
from sqlalchemy import func, and_


class DashboardService:
    """仪表盘业务逻辑"""
    
    @staticmethod
    def get_stats():
        """获取仪表盘统计数据"""
        total_rooms = Room.query.count()
        occupied_rooms = Room.query.filter_by(room_status_id=2).count()
        available_rooms = Room.query.filter_by(room_status_id=1).count()
        
        total_reservations = Reservation.query.count()
        confirmed_reservations = Reservation.query.filter_by(status=2).count()
        pending_reservations = Reservation.query.filter_by(status=1).count()
        
        # 计算今日入住
        today = datetime.now().date()
        today_start = datetime.combine(today, datetime.min.time())
        today_end = datetime.combine(today, datetime.max.time())
        
        today_checkins = Reservation.query.filter(
            Reservation.check_in >= today_start,
            Reservation.check_in <= today_end,
            Reservation.status.in_([2, 3])
        ).count()
        
        # 计算今日退房
        today_checkouts = Reservation.query.filter(
            Reservation.check_out >= today_start,
            Reservation.check_out <= today_end,
            Reservation.status.in_([2, 3])
        ).count()
        
        # 计算总收入
        total_revenue = db.session.query(func.sum(Reservation.total_price)).filter(
            Reservation.status.in_([2, 3])
        ).scalar() or 0
        
        return {
            'totalRooms': total_rooms,
            'occupiedRooms': occupied_rooms,
            'availableRooms': available_rooms,
            'occupancyRate': (occupied_rooms / total_rooms * 100) if total_rooms > 0 else 0,
            'totalReservations': total_reservations,
            'confirmedReservations': confirmed_reservations,
            'pendingReservations': pending_reservations,
            'todayCheckIns': today_checkins,
            'todayCheckOuts': today_checkouts,
            'todayRevenue': 0,
            'monthRevenue': float(total_revenue)
        }
    
    @staticmethod
    def get_checkin_trends(start_date=None, end_date=None, period='day'):
        """获取入住趋势数据"""
        if not start_date:
            start_date = datetime.now() - timedelta(days=30)
        if not end_date:
            end_date = datetime.now()
        
        if isinstance(start_date, str):
            start_date = datetime.strptime(start_date, '%Y-%m-%d')
        if isinstance(end_date, str):
            end_date = datetime.strptime(end_date, '%Y-%m-%d')
        
        # 确保end_date包含当天的所有时间
        if end_date and isinstance(end_date, datetime):
            end_date = end_date.replace(hour=23, minute=59, second=59)
        elif end_date and hasattr(end_date, 'date'):
            end_date = datetime.combine(end_date.date() if hasattr(end_date, 'date') else end_date, datetime.max.time())
        
        if period == 'day':
            data = db.session.query(
                func.date(Reservation.check_in).label('date'),
                func.count(Reservation.id).label('count')
            ).filter(
                Reservation.check_in >= start_date,
                Reservation.check_in <= end_date,
                Reservation.status.in_([2, 3])
            ).group_by(func.date(Reservation.check_in)).order_by(func.date(Reservation.check_in)).all()
        elif period == 'week':
            # MySQL使用YEARWEEK函数
            data = db.session.query(
                func.date_format(Reservation.check_in, '%Y-%u').label('week'),
                func.count(Reservation.id).label('count')
            ).filter(
                Reservation.check_in >= start_date,
                Reservation.check_in <= end_date,
                Reservation.status.in_([2, 3])
            ).group_by(func.date_format(Reservation.check_in, '%Y-%u')).order_by(func.date_format(Reservation.check_in, '%Y-%u')).all()
        else:  # month
            data = db.session.query(
                func.date_format(Reservation.check_in, '%Y-%m').label('month'),
                func.count(Reservation.id).label('count')
            ).filter(
                Reservation.check_in >= start_date,
                Reservation.check_in <= end_date,
                Reservation.status.in_([2, 3])
            ).group_by(func.date_format(Reservation.check_in, '%Y-%m')).order_by(func.date_format(Reservation.check_in, '%Y-%m')).all()
        
        return [{'date': str(item[0]), 'count': item[1]} for item in data]
    
    @staticmethod
    def get_room_distribution():
        """获取房间类型分布数据"""
        from models import RoomType
        
        data = db.session.query(
            RoomType.name.label('type_name'),
            Room.room_type_id,
            func.count(Room.id).label('count')
        ).join(RoomType, Room.room_type_id == RoomType.id).group_by(
            Room.room_type_id, RoomType.name
        ).all()
        
        return [{
            'type': item[0],
            'count': item[2],
            'room_type_id': item[1]
        } for item in data]
    
    @staticmethod
    def get_revenue_stats(start_date=None, end_date=None):
        """获取收入统计数据"""
        if not start_date:
            start_date = datetime.now() - timedelta(days=30)
        if not end_date:
            end_date = datetime.now()
        
        if isinstance(start_date, str):
            start_date = datetime.strptime(start_date, '%Y-%m-%d')
        if isinstance(end_date, str):
            end_date = datetime.strptime(end_date, '%Y-%m-%d')
        
        # 确保end_date包含当天的所有时间
        if end_date and isinstance(end_date, datetime):
            end_date = end_date.replace(hour=23, minute=59, second=59)
        elif end_date and hasattr(end_date, 'date'):
            end_date = datetime.combine(end_date.date() if hasattr(end_date, 'date') else end_date, datetime.max.time())
        
        data = db.session.query(
            func.date(Reservation.check_in).label('date'),
            func.sum(Reservation.total_price).label('revenue')
        ).filter(
            Reservation.check_in >= start_date,
            Reservation.check_in <= end_date,
            Reservation.status.in_([2, 3])
        ).group_by(func.date(Reservation.check_in)).order_by(func.date(Reservation.check_in)).all()
        
        return [{'date': str(item[0]), 'revenue': float(item[1]) if item[1] else 0} for item in data]
    
    @staticmethod
    def get_latest_reservations(limit=10):
        """获取最新预订"""
        from sqlalchemy.orm import joinedload
        
        reservations = Reservation.query.options(
            joinedload(Reservation.guest),
            joinedload(Reservation.room)
        ).order_by(
            Reservation.created_at.desc()
        ).limit(limit).all()
        
        return [{
            'id': r.id,
            'reservation_number': r.reservation_number,
            'guest_name': r.guest.name if r.guest else '',
            'room_number': r.room.room_number if r.room else '',
            'check_in': r.check_in.strftime('%Y-%m-%d') if r.check_in else None,
            'check_out': r.check_out.strftime('%Y-%m-%d') if r.check_out else None,
            'total_price': float(r.total_price) if r.total_price else 0,
            'status': r.status,
            'status_text': Reservation.STATUS_MAP.get(r.status, '未知状态')
        } for r in reservations]
    
    @staticmethod
    def get_upcoming_checkins(days=7):
        """获取即将入住的预订"""
        from sqlalchemy.orm import joinedload
        
        start_date = datetime.now()
        end_date = start_date + timedelta(days=days)
        
        reservations = Reservation.query.options(
            joinedload(Reservation.guest),
            joinedload(Reservation.room)
        ).filter(
            Reservation.status.in_([1, 2]),
            Reservation.check_in >= start_date,
            Reservation.check_in <= end_date
        ).order_by(Reservation.check_in.asc()).all()
        
        return [{
            'id': r.id,
            'reservation_number': r.reservation_number,
            'guest_name': r.guest.name if r.guest else '',
            'guest_phone': r.guest.phone if r.guest else '',
            'room_number': r.room.room_number if r.room else '',
            'check_in': r.check_in.strftime('%Y-%m-%d %H:%M:%S') if r.check_in else None,
            'status': r.status,
            'status_text': Reservation.STATUS_MAP.get(r.status, '未知状态')
        } for r in reservations]

